package com.vonchange.headb.utils.time.third;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 取自common-lang3的时间组件
 *
 * @author vonchange@163.com
 * @date 2015年10月9日 下午5:41:26
 * @since 1.0
 */
public class ADateUtils {
	   public static Date addMonths(final Date date, final int amount) {
	        return add(date, Calendar.MONTH, amount);
	    }
	   public static Date addWeeks(final Date date, final int amount) {
	        return add(date, Calendar.WEEK_OF_YEAR, amount);
	    }
	   public static Date addYears(final Date date, final int amount) {
	        return add(date, Calendar.YEAR, amount);
	    }
	  public static Date addDays(final Date date, final int amount) {
	        return add(date, Calendar.DAY_OF_MONTH, amount);
	    }
	  public static Date addHours(final Date date, final int amount) {
	        return add(date, Calendar.HOUR_OF_DAY, amount);
	    }
	  public static Date addMinutes(final Date date, final int amount) {
	        return add(date, Calendar.MINUTE, amount);
	    }
	  public static Date addSeconds(final Date date, final int amount) {
	        return add(date, Calendar.SECOND, amount);
	    }
	  public static Date addMilliseconds(final Date date, final int amount) {
	        return add(date, Calendar.MILLISECOND, amount);
	    }
	  private static Date add(final Date date, final int calendarField, final int amount) {
	        if (date == null) {
	            throw new IllegalArgumentException("The date must not be null");
	        }
	        final Calendar c = Calendar.getInstance();
	        c.setTime(date);
	        c.add(calendarField, amount);
	        return c.getTime();
	    } 
	public static Date parseDate(final String str, final String... parsePatterns) throws ParseException {
	        return parseDate(str, null, parsePatterns);
	    }
	  public static Date parseDate(final String str, final Locale locale, final String... parsePatterns) throws ParseException {
	        return parseDateWithLeniency(str, locale, parsePatterns, true);
	    }  
	  public static Date parseDateStrictly(final String str, final String... parsePatterns) throws ParseException {
	        return parseDateStrictly(str, null, parsePatterns);
	    }
	  public static Date parseDateStrictly(final String str, final Locale locale, final String... parsePatterns) throws ParseException {
		  return parseDateWithLeniency(str, null, parsePatterns, false);
	   }    
	  private static Date parseDateWithLeniency(
	            final String str, final Locale locale, final String[] parsePatterns, final boolean lenient) throws ParseException {
	        if (str == null || parsePatterns == null) {
	            throw new IllegalArgumentException("Date and Patterns must not be null");
	        }
	        
	        SimpleDateFormat parser;
	        if (locale == null) {
	            parser = new SimpleDateFormat();
	        } else {
	            parser = new SimpleDateFormat("", locale);
	        }
	        
	        parser.setLenient(lenient);
	        final ParsePosition pos = new ParsePosition(0);
	        for (final String parsePattern : parsePatterns) {

	            String pattern = parsePattern;

	            // LANG-530 - need to make sure 'ZZ' output doesn't get passed to SimpleDateFormat
	            if (parsePattern.endsWith("ZZ")) {
	                pattern = pattern.substring(0, pattern.length() - 1);
	            }
	            
	            parser.applyPattern(pattern);
	            pos.setIndex(0);

	            String str2 = str;
	            // LANG-530 - need to make sure 'ZZ' output doesn't hit SimpleDateFormat as it will ParseException
	            if (parsePattern.endsWith("ZZ")) {
	                str2 = str.replaceAll("([-+][0-9][0-9]):([0-9][0-9])$", "$1$2"); 
	            }

	            final Date date = parser.parse(str2, pos);
	            if (date != null && pos.getIndex() == str2.length()) {
	                return date;
	            }
	        }
	        throw new ParseException("Unable to parse the date: " + str, -1);
	    }

	
}
